﻿/******************************************************
* author :  cwj
* email  :  chenwenji_360@live.com 
* history:  created by cwj 2015/8/12 14:48:59 
* clrversion :4.0.30319.42000
******************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Soul.DataAccess.Common
{
    /// <summary>
    /// 当前上下文
    /// </summary>
    /// <typeparam name="TData"></typeparam>
    public abstract class ExecutionContextScopeBase<TData> : IDisposable
        where TData : class, ICloneable, new()
    {
        private ExecutionContext<TData> _originalContext = ExecutionContext<TData>.Current;

        public ExecutionContextScopeBase(ExecutionContextOption contextOption = ExecutionContextOption.Required)
        {
            switch (contextOption)
            {
                case ExecutionContextOption.RequiresNew:
                    {
                        ExecutionContext<TData>.Current = new ExecutionContext<TData>(new TData());
                        break;
                    }
                case ExecutionContextOption.Required:
                    {
                        ExecutionContext<TData>.Current = _originalContext ?? new ExecutionContext<TData>(new TData());
                        break;
                    }
                case ExecutionContextOption.Suppress:
                    {
                        ExecutionContext<TData>.Current = null;
                        break;
                    }
            }
        }
        public ExecutionContextScopeBase(DependentContext<TData> dependentContext)
        {
            if (dependentContext.OriginalThread == Thread.CurrentThread)
            {
                throw new InvalidOperationException("当前线程的上下文已经创建");
            }
            ExecutionContext<TData>.Current = dependentContext;
        }
        public virtual void Dispose()
        {
            ExecutionContext<TData>.Current = _originalContext;
        }

        public TData CurrentData
        {
            get { return ExecutionContext<TData>.Current == null ? default(TData) : ExecutionContext<TData>.Current.ScopData; }
        }

        public ExecutionContext<TData> Current
        {
            get { return ExecutionContext<TData>.Current; }
        }
    }

    public enum ExecutionContextOption
    {
        RequiresNew, Required, Suppress
    }
}
